package top.infopub.mgr.sys.web;


import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import top.infopub.generic.GenericController;
import top.infopub.mgr.common.cnst.Constants;
import top.infopub.mgr.common.page.ParamPage;
import top.infopub.mgr.common.vo.ErrorCodeEnum;
import top.infopub.mgr.common.vo.RspVo;
import top.infopub.mgr.sys.service.MenuService;
import top.infopub.mgr.sys.service.PurviewService;
import top.infopub.mgr.sys.service.RoleService;
import top.infopub.mgr.sys.service.RolepurviewService;
import top.infopub.mgr.sys.vo.CheckBoxTreeVo;
import top.infopub.mgr.sys.vo.LayTreeVo;
import top.infopub.model.sys.Menu;
import top.infopub.model.sys.Purview;
import top.infopub.model.sys.Role;
import top.infopub.model.sys.Rolepurview;
import top.infopub.security.util.SessionUserUtils;
//import top.infopub.security.util.SessionUserUtils;
import top.infopub.tdp.sys.service.CodeGeneratorConfigService;
import top.infopub.util.BoolUtils;

import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;


/**
 * 系统角色管理
 * @author Awoke
 * @version 2018年10月23日
 * @see RoleController
 * @since
 */
@Controller
@RequestMapping("/role")
public class RoleController extends GenericController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private PurviewService purviewService;

    @Autowired
    private RolepurviewService rolepurviewService;

    @Autowired
    private CodeGeneratorConfigService codeGeneratorConfigService;

    /** 编码类型： 系统角色编号*/
    private static final String PARAMGROUP_SYS_ROLE_CODE = "sys_role";

    /**
     * 角色列表
     * @return
     */
    @RequestMapping("/list")
    public String list() {
        return "sys/layrole-list";
    }

    /**
     * 根据条件获取获取角色列表数据
     * @param role
     * @return
     */
    @RequestMapping("/queryData")
    public @ResponseBody RspVo<Role> queryDataByCondition(Role role, ParamPage paramPage) {
        Page<Role> page = new Page<Role>();
        page.setPageNum(paramPage.getPage());
        page.setPageSize(paramPage.getLimit());
        page = roleService.selectPageByDomainWhere(page, role);
        return RspVo.getSuccessResponse(page.getTotal(), page.getResult());
    }

    /**
     * 新增||修改
     * @param role
     * @return 
     * @see
     */
    @RequestMapping("/save")
    public @ResponseBody RspVo<Role> save(Role role) {
        // 执行新增
        if (StringUtils.isBlank(role.getId())) {
            String sroleCode = codeGeneratorConfigService.generatorCode(PARAMGROUP_SYS_ROLE_CODE);
            role.setSroleCode(sroleCode);
            roleService.insert(role);
        }
        else// 执行修改
        {
            roleService.updateBySelective(role);
        }
        return RspVo.getSuccessResponse(role);
    }

    /**
     * 根据角色ID获取角色
     * @param id
     * @return
     */
    @RequestMapping("/getRoleById")
    public @ResponseBody RspVo<Role> getRoleById(String id) {
        Role role = roleService.selectByPrimaryKey(id);
        if (role == null) {
            role = new Role();
        }
        return RspVo.getSuccessResponse(role);
    }

    /**
     * 删除角色
     * @param checkboxId
     * @return
     * @throws Exception
     */
    @RequestMapping("/delete")
    public @ResponseBody RspVo<String> delete(String[] checkboxId) {
        roleService.delete(checkboxId);
        return RspVo.getSuccessResponse();
    }

    /**
     * 保存角色权限
     * @param checkPurviewId
     * @param roleId
     * @return 
     * @see
     */
    @RequestMapping("/saveRolePurview")
    @SuppressWarnings("unchecked")
    public @ResponseBody RspVo<String> saveRolePurview(String checkPurviewId, String roleId,
                                                       String clickMenuIds) {
        if (StringUtils.isBlank(roleId) || StringUtils.isBlank(checkPurviewId)
            || StringUtils.isBlank(clickMenuIds)) {
            return ErrorCodeEnum.ERROR_COMMON_SYSTEM.getRspVo(Constants.BAD_PARAMETERS_REQUEST);
        }
        roleService.saveRolePurviewByClickMenu(checkPurviewId, roleId, clickMenuIds);
        return RspVo.getSuccessResponse();
    }

    /***
     * 角色分配权限树
     * @return
     */
    @RequestMapping("/getCheckBoxTree")
    @Deprecated
    public @ResponseBody List<CheckBoxTreeVo> getCheckBoxTree(String roleId) {
        if (null == roleId) {
            return null;
        }
        // 获取所有菜单
        List<Menu> menuList = menuService.selectByEntityWhere(new Menu());
        // 获取所有权限
        List<Purview> listPurview = purviewService.selectByEntityWhere(new Purview());

        Rolepurview paramRolepurview = new Rolepurview();
        paramRolepurview.setSroleId(roleId);
        List<Rolepurview> rolepurviewList = rolepurviewService.selectByEntityWhere(paramRolepurview);
        // 构造treeMap
        Map<String, CheckBoxTreeVo> treeMap = new LinkedHashMap<String, CheckBoxTreeVo>();
        CheckBoxTreeVo root = new CheckBoxTreeVo();
        // 把菜单加到Map里
        for (Menu menu : menuList) {
            CheckBoxTreeVo tree = new CheckBoxTreeVo();
            tree.setBisroot(menu.getBisRoot());
            tree.setId(menu.getId());
            tree.setText(menu.getSname());
            tree.setLeaf(false);
            tree.setSparentid(menu.getSparentId());
            tree.setHref("");
            //tree.setIconCls("resource");
            treeMap.put(menu.getId(), tree);
        }
        // 循环所有权限码
        for (Purview purview : listPurview) {
            CheckBoxTreeVo tree = new CheckBoxTreeVo();
            tree.setBisroot("0");
            tree.setId(purview.getId());
            tree.setText(purview.getSpurName());
            tree.setLeaf(true);
            tree.setSparentid(purview.getSparentId());
            if (rolepurviewList != null) {
                Iterator<Rolepurview> it = rolepurviewList.iterator();
                while (it.hasNext()) {
                    Rolepurview rolepurview = it.next();
                    if (rolepurview.getSpurviewId().equals(purview.getId())) {
                        tree.setChecked(true);
                        break;
                    }
                }
            }
            treeMap.put(purview.getId(), tree);
        }
        // 递归构造树
        Iterator<Map.Entry<String, CheckBoxTreeVo>> it = treeMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, CheckBoxTreeVo> entry = it.next();
            CheckBoxTreeVo tree = entry.getValue();
            if (tree.getBisroot().equals("1")) {// 如果是根节点
                root.getChildren().add(tree);
            }
            else {
                CheckBoxTreeVo parent = treeMap.get(tree.getSparentid());// 根据父Id查询
                if (parent != null) {
                    parent.getChildren().add(tree);
                }
            }
        }
        // 选中有权限码的节点及父节点
        root.removeNoRight();
        root.checkall();
        if (root.getChildren().size() > 0) {
            root.getChildren().get(0).setExpanded(true);
        }
        return root.getChildren();
    }

    /***
     * 角色分配权限树
     * @return
     */
    @RequestMapping("/getLayTree")
    public @ResponseBody List<LayTreeVo> getLayTree(String roleId) {
        if (null == roleId) {
            return null;
        }
        // 获取菜单
        List<Menu> menuList = Lists.newArrayList();
        // 获取权限
        List<Purview> listPurview = Lists.newArrayList();
        // 如果当前账号不是admin，则角色分配权限树时，展示的树为[当前用户]拥有的菜单权限，而admin可分配全部权限
        if (!"admin".equals(SessionUserUtils.getSessionUserName())) {
            // 获取当前拥有的菜单和权限
            menuList = menuService.queryByUserId(SessionUserUtils.getSessionUserId());
            listPurview = purviewService.selectByUserId(SessionUserUtils.getSessionUserId());
        }
        else {
            // admin获取所有菜单/权限
            menuList = menuService.selectByEntityWhere(new Menu());
            listPurview = purviewService.selectByEntityWhere(new Purview());
        }

        //Rolepurview paramRolepurview = new Rolepurview();
        //paramRolepurview.setSroleId(roleId);
        //List<Rolepurview> rolepurviewList = rolepurviewService.selectByEntityWhere(paramRolepurview);

        // 哪些菜单已经选中
        List<String> checkedMenus = rolepurviewService.selectMenuIdsByRoleId(roleId);
        boolean flag = (checkedMenus != null && checkedMenus.size() > 0);
        // 构造treeMap
        Map<String, LayTreeVo> treeMap = new LinkedHashMap<String, LayTreeVo>();
        LayTreeVo root = new LayTreeVo();
        // 把菜单加到Map里
        for (Menu menu : menuList) {
            LayTreeVo tree = new LayTreeVo();
            tree.setBisroot(menu.getBisRoot());
            tree.setId(menu.getId());
            tree.setTitle(menu.getSname());
            tree.setLeaf(BoolUtils.toBooleanObject(menu.getBisLeaf()));
            tree.setSparentid(menu.getSparentId());
            tree.setHref("");
            // 控制展开项
            /*if ("-1".equals(menu.getSparentId())) {
                tree.setSpread(true);
                //tree.setDisabled(true);// 不可选，必须让其点击展开 以触发后续的异步事情
            }*/
            tree.setSpread(true);
            //tree.setIconCls("resource");
            treeMap.put(menu.getId(), tree);

            // 已选择的菜单前面增加前缀
            if (flag && checkedMenus.contains(tree.getId())) {
                tree.setTitle("★ " + tree.getTitle());
            }
        }
        // 用于存放最后一级菜单的id
        Set<String> lastStepSet = Sets.newHashSet();
        // 循环所有权限码
        for (Purview purview : listPurview) {
            LayTreeVo tree = new LayTreeVo();
            tree.setBisroot("0");
            tree.setId(purview.getId());
            tree.setTitle(purview.getSpurName());
            tree.setLeaf(true);
            tree.setDisabled(false);
            tree.setSparentid(purview.getSparentId());
            lastStepSet.add(purview.getSparentId());
            // 此次不处理checked 采用异步方式 
            /*if (rolepurviewList != null) {
                Iterator<Rolepurview> it = rolepurviewList.iterator();
                while (it.hasNext()) {
                    Rolepurview rolepurview = it.next();
                    if (rolepurview.getSpurviewId().equals(purview.getId())) {
                        tree.setChecked(true);
                        break;
                    }
                }
            }*/
            treeMap.put(purview.getId(), tree);
        }
        // 递归构造树
        Iterator<Map.Entry<String, LayTreeVo>> it = treeMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, LayTreeVo> entry = it.next();
            LayTreeVo tree = entry.getValue();
            if (tree.getBisroot().equals("1") && !tree.isLeaf()) {// 如果是根节点
                root.getChildren().add(tree);
                tree.setChecked(false);
            }
            else {
                LayTreeVo parent = treeMap.get(tree.getSparentid());// 根据父Id查询
                if (parent != null) {
                    parent.getChildren().add(tree);
                }
            }
            // 设置最后一级菜单flag
            if (lastStepSet.contains(tree.getId())) {
                tree.setDisabled(false);
                tree.setLastStep(true);
                tree.setSpread(false);// 最后一级关闭
            }
        }
        // 选中有权限码的节点及父节点
        root.removeNoRight();
        return root.getChildren();
    }

    /***
     * 异步获得 某个角色在某个菜单下已分配的权限
     * 角色分配权限树 checked
     * @return
     */
    @RequestMapping("/getAsynLayTreeChecked")
    public @ResponseBody RspVo<List<Rolepurview>> getAsynLayTreeChecked(String roleId,
                                                                        String clickMenuId) {
        if (null == roleId || null == clickMenuId) {
            return RspVo.getFailureResponse(-1, "无效的参数~");
        }
        List<Rolepurview> rolepurviewList = rolepurviewService.selectPurviewByRoleAndMenu(roleId,
            clickMenuId);
        return RspVo.getSuccessResponse(rolepurviewList);
    }

}
